/******************************************************************************
Module:  DiskFullException.cs
Notices: Copyright (c) 2006 Jeffrey Richter
******************************************************************************/


using System;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Permissions;


///////////////////////////////////////////////////////////////////////////////


// Allow instances of DiskFullException to be serialized
[Serializable]
public sealed class DiskFullException : Exception, ISerializable {
   // Define a private field
   private String m_diskpath;

   // Define a read-only property that returns the field
   public String DiskPath { get { return m_diskpath; } }

   // Override the Message property to include our field (if set)
   public override String Message {
      get {
         if (m_diskpath == null) return base.Message;
         StringBuilder msg = new StringBuilder(base.Message);
         msg.AppendLine(" (DiskPath=" + m_diskpath +")");
         return msg.ToString();
      }
   }

   // The three public constructors
   public DiskFullException() : base() {  }
   public DiskFullException(String message) : base(message) { }
   public DiskFullException(String message, Exception innerException)
      : base(message, innerException) { }

   // Define additional constructors that set the field
   public DiskFullException(String message, String diskpath)
      : this(message) { m_diskpath = diskpath; }

   public DiskFullException(String message, String diskpath, Exception innerException) 
      : this(message, innerException) { m_diskpath = diskpath; }

   // The one constructor for deserialization
   // Since this class is sealed, this constructor is private
   // If this class were not sealed, this constructor should be protected
   private DiskFullException(SerializationInfo info, StreamingContext context)
      : base(info, context) { 
      // Deserialize each field
      m_diskpath = info.GetString("DiskPath");
   }

   // Because at least 1 field is defined, define the serialization method
   [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
   public override void GetObjectData(
      SerializationInfo info, StreamingContext context) {
      // Serialize each field
      info.AddValue("DiskPath", m_diskpath);

      // Let the base type serialize its fields
      base.GetObjectData(info, context);
   }
}


///////////////////////////////////////////////////////////////////////////////


// The code below tests the serialization of the exception
public sealed class Program {
   public static void Main() {
      // Construct a DiskFullException object
      DiskFullException e =
         new DiskFullException("The disk volume is full", @"C:\");

      // Serialize the DiskFullException object
      FileStream fs = new FileStream("Test", FileMode.Create);
      IFormatter f = new BinaryFormatter();
      f.Serialize(fs, e);
      fs.Close();

      // Deserialize the DiskFullException object and check it's fields
      fs = new FileStream("Test", FileMode.Open);
      e = (DiskFullException) f.Deserialize(fs);
      fs.Close();
      Console.WriteLine("Type: {1}{0}DiskPath: {2}{0}Message: {3}",
         Environment.NewLine, e.GetType(), e.DiskPath, e.Message);
   }
}


//////////////////////////////// End of File //////////////////////////////////
